package xyz.scootaloo.oj.offer

import org.junit.Test
import xyz.scootaloo.console.app.support.Tester
import java.lang.StringBuilder

/**
 * @author flutterdash@qq.com
 * @since 2021/4/10 11:24
 */
class P08 {

    private fun myAtoi(s: String): Int {
        val cache = preCheck(s)
        var res:Long = 0
        var carry:Long = 1
        val flag = cache[0] == '-'
        val limit:Long = if (flag) 2147483648 else 2147483647
        for (idx in (cache.length - 1) downTo 1) {
            val num = (cache[idx] - '0') * carry
            res += num
            if (res >= limit)
                return ret(cache, null)
            carry *= 10
        }
        return ret(cache, res)
    }

    private fun ret(cache: StringBuilder, num: Long?): Int {
        val flag = cache[0] == '-'
        return if (num == null) {
            if (flag) Int.MIN_VALUE else Int.MAX_VALUE
        } else {
            if (flag) -(num.toInt()) else num.toInt()
        }
    }

    private fun preCheck(str: String): StringBuilder {
        val cache = StringBuilder().append(' ')
        var pos = 0 // index of cache
        while (pos < str.length && str[pos] == ' ') pos++
        while (pos < str.length) {
            val c = str[pos]
            when {
                c == '-' || c == '+' -> {
                    if (cache[0] == ' ' && cache.length == 1) {
                        if (cache.length > 1) return StringBuilder().append('+')
                        cache[0] = c
                    } else return cache
                }
                c.isDigit() -> { cache.append(c) }
                else -> { return cache }
            }
            pos++
        }
        return cache
    }

    @Test
    fun test0() {
        Tester.createTest(this::myAtoi)
            .addCase("42", 42)
            .addCase("    -42", -42)
            .addCase("4193 with words", 4193)
            .addCase("words and 987", 0)
            .addCase("-91283472332", -2147483648)
            .addCase("3.1415", 3)
            .addCase("00000-42a1234", 0)
            .addCase("-2147483647", -2147483647)
            .addCase("123-", 123)
            .testAndShow()
    }

}
